package tk.sunlatus.project.security.encode.impl;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.security.jca.ProviderList;
import sun.security.jca.Providers;
import tk.sunlatus.project.common.constants.SunlatusConstants;
import tk.sunlatus.project.security.encode.Encoder;
import tk.sunlatus.project.security.key.KeyManager;

public class EncoderIDEAImpl implements Encoder {

    /**
     * 对data进行加密
     * 
     * @param keyByte
     *            字节数组
     * @param data
     *            字节数组
     * @return 加密后的数据
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] encrypt(byte[] keyByte, byte[] data) {
        Key key = KeyManager.bytesToKey(keyByte);
        return encrypt(key, data);
    }

    /**
     * 对data进行加密
     * 
     * @param keyByte
     *            字节数组
     * @param data
     *            字符串
     * @return 加密后的数据
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] encrypt(byte[] keyByte, String data) {
        return encrypt(keyByte, data.getBytes(SunlatusConstants.EncodeConstant.CHARSET));
    }

    /**
     * 对data进行加密
     * 
     * @param key
     *            Key
     * @param data
     *            字节数组
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] encrypt(Key key, byte[] data) {
        try {
            // Security.addProvider(new BouncyCastleProvider());
            addProvider(new BouncyCastleProvider());

            Cipher cipher = Cipher.getInstance(SunlatusConstants.EncodeConstant.ALGORITHM_IDEA);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(data);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    private void addProvider(Provider provider) {

        ProviderList list = Providers.getFullProviderList();
        if (list.getIndex(provider.getName()) > -1) {
            return;
        }
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 
     * @param key
     *            Key
     * @param data
     *            字符串
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] encrypt(Key key, String data) {
        return encrypt(key, data.getBytes(SunlatusConstants.EncodeConstant.CHARSET));
    }

}
